home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Pascal Super Library
/
Pascal Super Library (CW International)(1997).bin
/
SHELLS
/
TPSHELL
/
SHELL.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1986-05-23
|
4KB
|
125 lines
{$V-}
{ This procedure allows a Turbo Pascal program to execute any DOS
command string. COMMAND.COM does the work of looking for command extentions,
(.COM, .EXE, or .BAT), internal commands, piping, redirection, etc.
Commands can be .BAT files, DOS commands or any other compiled programs,
but the DOS SET, PROMPT, and PATH commands cannot be used.
Written by:
Bill Mayne
9707 Lawndale Dr.
Silver Spring, MD 20901
Based on work by:
Bela Lubkin
Borland International Technical Support
This version differs from Lubkin's in that:
(1) It always uses COMMAND.COM. Consequently, the code is a bit simpler
and it is easier to use, though not quite as efficient in some cases.
It does not allow you to over-ride or by-pass the normal path search.
(In exceptional cases that might be disadvantage, normally it is what you
want.) The both the source and object code are somewhat smaller.
(2) The FCBs passed to the subprocess contain blanks for the filename.ext
rather than the name of the command. (It works anyway. I don't know the
purpose of these FCBs. It shortens the code some to do it this way.)
(3) The search of the pathname of COMMAND.COM in the environment string is not
simplified, saving some storage.
(4) It is changed to a procedure instead of a function, but it would be
easy to change it back if you prefer a function.
The value returned in RC is the value returned by DOS after the DOS call.
See a DOS technical reference manual for more information on it.
Suffice it to say that anything nonzero means something went wrong.
VERY IMPORTANT NOTE: you MUST use the Options menu of Turbo Pascal to
restrict the amount of free dynamic memory used by your program. Only the
memory that is not used by the heap is available for use by other programs.
A very simple program needs about $40 paragraphs (1K bytes). A minimum of
$100 (4K) is suggested. Some programs may obviously need more. }
type
ShellStr=string[127];
{ This is the only definition (except the procedure itself) known to
the outside program, and the only one needed by the procedure.
This level of independence is desirable for "toolbox" include files
which may be used in many different programs. }
procedure Shell(CommandLine: ShellStr;var rc:integer);
Type
Env=Array [0..32767] Of Char;
Var
EPtr: ^Env;
I: Integer;
Regs: Record Case Integer Of
1: (AX,BX,CX,DX,BP,SI,DI,DS,ES,Flags: Integer);
2: (AL,AH,BL,BH,CL,CH,DL,DH: Byte);
End;
FCB1,FCB2: Array [0..36] Of Byte;
PathName: String[66];
CommandTail: String[135];
ParmTable: Record
EnvSeg: Integer;
ComLin: ^Integer;
FCB1Pr: ^Integer;
FCB2Pr: ^Integer;
End;
Begin
PathName:=PathName+#0;
With Regs Do
Begin
{Create FCBs for EXEC call}
FillChar(FCB1,Sizeof(FCB1),0);
FillChar(FCB1[2],11,ord(' ')); {blank filename.ext}
FillChar(FCB2,Sizeof(FCB2),0);
FillChar(FCB2[2],11,ord(' ')); {blank filename.ext}
(* May not need this -
{Deallocate unused memory}
ES:=CSeg;
BX:=SSeg-CSeg+MemW[CSeg:MemW[CSeg:$0101]+$112];
AH:=$4A;
MsDos(Regs);
*)
{Scan the env and set DS:DX ==> pathname of COMMAND.COM}
DS:=MemW[CSeg:$002C];
DX:=0;
PathName[0]:=chr(8);
move(Mem[DS:0],PathName[1],8);
while PathName<>'COMSPEC=' do
begin
repeat
DX:=DX+1;
until Mem[DS:DX]=0;
DX:=DX+1;
move(Mem[DS:DX],Pathname[1],8);
end;
DX:=DX+8;
{Now comes the EXEC (DOS function $4B) call}
CommandTail:=' /C '+CommandLine+^M;
CommandTail[0]:=Pred(CommandTail[0]);
With ParmTable Do
Begin
EnvSeg:=MemW[CSeg:$002C];
ComLin:=Addr(CommandTail);
FCB1Pr:=Addr(FCB1);
FCB2Pr:=Addr(FCB2);
End;
ES:=Seg(ParmTable);
BX:=Ofs(ParmTable);
AX:=$4B00;
MsDos(Regs); { Call subprocess }
{Pass the return code back to the caller}
If (Flags And 1)<>0 Then rc:=AX
Else rc:=0;
End;
End;